﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Moq;
using FriendsNearby.Services;
using System.ComponentModel.Design;
using Twitter.Tests;
using System.Linq.Expressions;

namespace FriendsNearbyBot.Tests
{
	[TestFixture]
	public class NearbyNotifierProcessorFixture : TestBase
	{
		IServiceProvider services;
		Mock<IPeopleNearbyService> peopleNearbyService;
		Mock<ILocationService> locationService;
		Mock<IUsersService> usersService;
		Guid me = Guid.Empty;

		[SetUp]
		public void CreateServices()
		{
			var services = new ServiceContainer();
			this.services = services;

			peopleNearbyService = new Mock<IPeopleNearbyService>();
			usersService = new Mock<IUsersService>();
			locationService = new Mock<ILocationService>();

			services.AddService(peopleNearbyService.Object);
			services.AddService(usersService.Object);
			services.AddService(locationService.Object);
		}

		[Test]
		public void ShouldSendNiceEmtyNotification()
		{
			usersService.Expect(x => x.QueryUserRegistry(It.IsAny<Expression<Func<UserRegistry, bool>>>())).Returns(
				new UserRegistry { UserID = me });
			peopleNearbyService.Expect(x => x.GetNotificationsForUser(me)).Returns(new List<string>());
			locationService.Expect(x => x.SaveLastNotificationDate(me, It.IsAny<DateTime>()));

			// Warn: 
			MemoryBotClient bot = new MemoryBotClient("fnb");
			MemoryBotClient user = new MemoryBotClient("fnbtestb");
			bot.SetBuddy(user);
			user.SetBuddy(bot);

			NearbyNotifierProcessor processor = new NearbyNotifierProcessor(usersService.Object, locationService.Object, peopleNearbyService.Object, CreateMessageBuilder());
			var msg = CreateMessage("new", user.ScreenName, bot.ScreenName);
			Assert.IsTrue(processor.CanProcess(msg));
			processor.Process(bot, msg);

			Assert.AreEqual(1, user.Messages.GetAll().Count());
			Assert.AreEqual("No new nearby friends.", user.Messages.GetAll().First().Text);
		}

		private object Expression<T1>(string p)
		{
			throw new NotImplementedException();
		}

		[Test]
		public void ShouldSendNiceSingleNotification()
		{
			usersService.Expect(x => x.QueryUserRegistry(It.IsAny<Expression<Func<UserRegistry, bool>>>())).Returns(
				new UserRegistry { UserID = me });
			peopleNearbyService.Expect(x => x.GetNotificationsForUser(me)).Returns(
				new List<string>(new string[] { "User1" }));
			locationService.Expect(x => x.SaveLastNotificationDate(me, It.IsAny<DateTime>()));

			// Warn: 
			MemoryBotClient bot = new MemoryBotClient("fnb");
			MemoryBotClient user = new MemoryBotClient("fnbtestb");
			bot.SetBuddy(user);
			user.SetBuddy(bot);

			NearbyNotifierProcessor processor = new NearbyNotifierProcessor(usersService.Object, locationService.Object, peopleNearbyService.Object, CreateMessageBuilder());
			var msg = CreateMessage("new", user.ScreenName, bot.ScreenName);
			Assert.IsTrue(processor.CanProcess(msg));
			processor.Process(bot, msg);

			Assert.AreEqual(1, user.Messages.GetAll().Count());
			Assert.AreEqual("User1 is now nearby.", user.Messages.GetAll().First().Text);
		}

		[Test]
		public void ShouldSendNiceFormatForManyNotification()
		{
			usersService.Expect(x => x.QueryUserRegistry(It.IsAny<Expression<Func<UserRegistry, bool>>>())).Returns(
				new UserRegistry { UserID = me });
			peopleNearbyService.Expect(x => x.GetNotificationsForUser(me)).Returns(
				new List<string>(new string[] { "User1", "User2", "User3", "User4" }));
			locationService.Expect(x => x.SaveLastNotificationDate(me, It.IsAny<DateTime>()));

			// Warn: 
			MemoryBotClient bot = new MemoryBotClient("fnb");
			MemoryBotClient user = new MemoryBotClient("fnbtestb");
			bot.SetBuddy(user);
			user.SetBuddy(bot);

			NearbyNotifierProcessor processor = new NearbyNotifierProcessor(usersService.Object, locationService.Object, peopleNearbyService.Object, CreateMessageBuilder());
			var msg = CreateMessage("new", user.ScreenName, bot.ScreenName);
			Assert.IsTrue(processor.CanProcess(msg));
			processor.Process(bot, msg);

			Assert.AreEqual(1, user.Messages.GetAll().Count());
			Assert.AreEqual("User1, User2, User3 and User4 are now nearby.", user.Messages.GetAll().First().Text);
		}
	}
}
